/* 
  Proxy 代理 
  * defineProperty只能监视属性的读写，Proxy可以监视到更多操作，例如delete和对象方法调用等，Proxy是非侵入的方式监管对象
  
  * Proxy的一些方法（handler方法 => 触发方式）
    * get => 读取某个属性
    * et => 写入某个属性
    * as => in 操作符
    * eleteProperty => delete 操作符
    * etPrototypeOf => Object.getPrototypeOf()
    * etPrototypeOf => Object.setPrototypeOf()
    * sExtensible => Object.isExtensible()
    * erventExtensions => Object.perventExtensions()
    * etOwnPropertydescriptor => Object.getOwnPropertydescriptor()
    * efineProperty => Object.defineProperty()
    * wnKeys => Object.getOwnPropertyNames()、Object.getOwnPropertySymbols()
    * pply => 调用一个函数
    * onstruct => 用 new 调用一个函数
*/

const obj = {
  a: 123,
  b: 456,
  c: {
    a: 1,
  }
}

const proxyObj = new Proxy(obj, {
  get (target, property) {
    console.log(target, property)
    return property in target ? target[property] : 'defaultValue'
  },
  set (target, property, value) {
    if (property === 'a' && !Number.isInteger(value)) {
      throw new TypeError(`${value} is not an int`)
    }
    target[property] = value
  },
  deleteProperty (target, property) {
    console.log(target, property)
    if (property === 'a') {
      throw new Error(`${property} can not be deleted`)
    }
    delete target[property]
  }
})
// proxyA.a = 100
// console.log(proxyA.a)
delete proxyObj.b
console.log(proxyObj)
